/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package percussiongenerator.input;

import java.io.File;
import java.util.ArrayList;
import javax.sound.midi.Instrument;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.jfonia.model.Sequence;
import org.jfonia.model.Staff;
import org.jfonia.model.TempoMap;
import org.jfonia.model.TempoNode;
import org.jfonia.model.elements.TimeSignature;
import org.jfonia.model.quantize.BPMQuantizer;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import percussiongenerator.model.Track;
import percussiongenerator.sound.SimpleInstrument;

/**
 *
 * @author Jannes Plyson
 */
public class DataParser {
    ArrayList<Track> readFile(File file, Instrument[] instruments){
        ArrayList<Track> tracks = new ArrayList<Track>();
        try{
            DocumentBuilderFactory dbfac = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = dbfac.newDocumentBuilder();
            Document doc = docBuilder.parse(file);
            NodeList trackList = doc.getElementsByTagName("Track");
            for(int i=0; i < trackList.getLength(); i++){
                Node nodeTrack = trackList.item(i);
                long length = Long.parseLong(nodeTrack.getAttributes().getNamedItem("length").getNodeValue());
                InputNotes inputNotes = new InputNotes();
                NodeList toneList = nodeTrack.getFirstChild().getChildNodes();
                for(int j = 0; j < toneList.getLength(); j++){
                    Node tone = toneList.item(j);
                    long start = Long.parseLong(tone.getAttributes().getNamedItem("start").getNodeValue());
                    long end;
                    if(j < toneList.getLength()-1){
                        end = Long.parseLong(toneList.item(j+1).getAttributes().getNamedItem("start").getNodeValue());
                    }else{
                        end = length;
                    }
                    int pitch = Integer.parseInt(tone.getAttributes().getNamedItem("pitch").getNodeValue());
                    int velocity = Integer.parseInt(tone.getAttributes().getNamedItem("velocity").getNodeValue());
                    inputNotes.addInput(start, end, pitch, velocity);
                }
                Staff staff = inputNotes.getStaff();
                int smallestValue = Integer.parseInt(nodeTrack.getAttributes().getNamedItem("smallestValue").getNodeValue());
                staff.getQuantizerNode().setQuantizer(new BPMQuantizer(smallestValue));
                int bpm = Integer.parseInt(nodeTrack.getAttributes().getNamedItem("bpm").getNodeValue());
                TempoMap tempoMap = new TempoMap();
                TempoNode tempoNode = new TempoNode();
                tempoNode.setBPM(bpm);
                tempoNode.setDifference(staff.getLength());
                tempoMap.add(tempoNode);
                staff.setTempoMap(tempoMap);
                int nominator = Integer.parseInt(nodeTrack.getAttributes().getNamedItem("nominator").getNodeValue());
                int denominator = Integer.parseInt(nodeTrack.getAttributes().getNamedItem("denominator").getNodeValue());
                TimeSignature ts = new TimeSignature(staff.getLength()).setNominator(nominator).setDenominator(denominator);
                Sequence<TimeSignature> seq = new Sequence<TimeSignature>(TimeSignature.class);
                seq.add(ts);
                staff.addSequence(seq);
                Track track = new Track(staff);
                String instrumentName = nodeTrack.getAttributes().getNamedItem("instrumentName").getNodeValue();
                int drumkitPitch = Integer.parseInt(nodeTrack.getAttributes().getNamedItem("drumkitPitch").getNodeValue());
                Instrument instrument = getInstrument(instrumentName, instruments);
                if(instrument != null){
                    track.setInstrument(new SimpleInstrument(instrument, drumkitPitch));
                }
                tracks.add(track);
            }
        }catch(Exception exc){
            System.err.println(exc.getMessage());
        }
        return tracks;
    }

    public Instrument getInstrument(String instrumentName, Instrument[] instruments){
        int i = 0;
        while(i < instruments.length && !instruments[i].toString().equals(instrumentName)){
            i++;
        }
        if(i < instruments.length){
            return instruments[i];
        }else{
            return null;
        }
    }
}
